<template>
  <div
    v-loading="!visible"
    element-loading-text="数据加载中..."
    :style="!visible ? 'height: 100%' : 'height: 100%'"
    class="app-container"
  >
    <div>
      <el-card class="box-card">
        <div style="color: #666; font-size: 15px">
          <svg-icon icon-class="system" style="margin-right: 5px" />
          <span>系统：{{ sys.os }}</span>
          <span>IP：{{ sys.ip }}</span>
          <span>项目已不间断运行：{{ sys.day }}</span>
          <el-icon class="el-icon-refresh" @click="handleRefresh">
            <Refresh />
          </el-icon>
        </div>
      </el-card>
      <el-card class="box-card">
        <template #header>
          <div class="clearfix">
            <span style="font-weight: bold; color: #666; font-size: 15px">
              状态
            </span>
          </div>
        </template>
        <el-row>
          <el-col :span="6" style="margin-bottom: 10px">
            <div class="title">CPU使用率</div>
            <el-tooltip placement="top-end">
              <template #content>
                <div style="font-size: 12px">
                  <div style="padding: 3px">
                    {{ cpu.name }}
                  </div>
                  <div style="padding: 3px">
                    {{ cpu.packageCount }}
                  </div>
                  <div style="padding: 3px">
                    {{ cpu.core }}
                  </div>
                  <div style="padding: 3px">
                    {{ cpu.logic }}
                  </div>
                </div>
              </template>
              <div class="content">
                <el-progress
                  type="dashboard"
                  :percentage="parseFloat(cpu.used)"
                />
              </div>
            </el-tooltip>
            <div class="footer">{{ cpu.coreNumber }} 核心</div>
          </el-col>
          <el-col :span="6" style="margin-bottom: 10px">
            <div class="title">内存使用率</div>
            <el-tooltip placement="top-end">
              <template #content>
                <div style="font-size: 12px">
                  <div style="padding: 3px">总量：{{ memory.total }}</div>
                  <div style="padding: 3px">已使用：{{ memory.used }}</div>
                  <div style="padding: 3px">空闲：{{ memory.available }}</div>
                </div>
              </template>
              <div class="content">
                <el-progress
                  type="dashboard"
                  :percentage="parseFloat(memory.usageRate)"
                />
              </div>
            </el-tooltip>
            <div class="footer">{{ memory.used }} / {{ memory.total }}</div>
          </el-col>
          <el-col :span="6" style="margin-bottom: 10px">
            <div class="title">交换区使用率</div>
            <el-tooltip placement="top-end">
              <template #content>
                <div style="font-size: 12px">
                  <div style="padding: 3px">总量：{{ swap.total }}</div>
                  <div style="padding: 3px">已使用：{{ swap.used }}</div>
                  <div style="padding: 3px">空闲：{{ swap.available }}</div>
                </div>
              </template>
              <div class="content">
                <el-progress
                  type="dashboard"
                  :percentage="parseFloat(swap.usageRate)"
                />
              </div>
            </el-tooltip>
            <div class="footer">{{ swap.used }} / {{ swap.total }}</div>
          </el-col>
          <el-col :span="6" style="margin-bottom: 10px">
            <div class="title">磁盘使用率</div>
            <div class="content">
              <el-tooltip placement="top-end">
                <template #content>
                  <div style="font-size: 12px">
                    <div style="padding: 3px">总量：{{ disk.total }}</div>
                    <div style="padding: 3px">空闲：{{ disk.available }}</div>
                  </div>
                </template>
                <div class="content">
                  <el-progress
                    type="dashboard"
                    :percentage="parseFloat(disk.usageRate)"
                  />
                </div>
              </el-tooltip>
            </div>
            <div class="footer">{{ disk.used }} / {{ disk.total }}</div>
          </el-col>
        </el-row>
      </el-card>

      <div>
        <el-row :gutter="6">
          <el-col :span="12" style="margin-bottom: 10px">
            <el-card class="box-card">
              <template #header>
                <div class="clearfix">
                  <span style="font-weight: bold; color: #666; font-size: 15px">
                    CPU使用率监控
                  </span>
                </div>
              </template>
              <div id="cpu_chart" style="width: 100%; height: 300px" />
            </el-card>
          </el-col>
          <el-col :span="12" style="margin-bottom: 10px">
            <el-card class="box-card">
              <template #header>
                <div class="clearfix">
                  <span style="font-weight: bold; color: #666; font-size: 15px">
                    内存使用率监控
                  </span>
                </div>
              </template>
              <div id="memory_chart" style="width: 100%; height: 300px" />
            </el-card>
          </el-col>
        </el-row>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
defineOptions({
  name: "ServerMonitor",
  inheritAttrs: false,
});
import * as echarts from "echarts";
import MonitorAPI, {
  ServerVO,
  SysVO,
  CpuVO,
  StorageVO,
} from "@/api/monitor/index";

const defaultData = {
  total: "0",
  available: "0",
  used: "0",
  usageRate: "0",
};
const visible = ref(false);
const sys = ref<SysVO>({});
const cpu = ref<CpuVO>({
  used: "0",
});
const memory = ref<StorageVO>(defaultData);
const swap = ref<StorageVO>(defaultData);
const disk = ref<StorageVO>(defaultData);
const cpuChart: Ref<echarts.ECharts | null> = ref(null);
const memoryChart: Ref<echarts.ECharts | null> = ref(null);
//定时器
const intervalId = ref();

const cpuOptions: {
  tooltip: {
    trigger: string;
  };
  xAxis: {
    type: string;
    boundaryGap: boolean;
    data: string[];
  };
  yAxis: {
    type: string;
    min: number;
    max: number;
    interval: number;
  };
  series: [
    {
      data: number[];
      type: string;
      areaStyle: {
        normal: {
          color: string;
        };
      };
      itemStyle: {
        normal: {
          color: string;
          lineStyle: {
            color: string;
          };
        };
      };
    },
  ];
} = {
  tooltip: {
    trigger: "axis",
  },
  xAxis: {
    type: "category",
    boundaryGap: false,
    data: [],
  },
  yAxis: {
    type: "value",
    min: 0,
    max: 100,
    interval: 20,
  },
  series: [
    {
      data: [],
      type: "line",
      areaStyle: {
        normal: {
          color: "rgb(32, 160, 255)", // 改变区域颜色
        },
      },
      itemStyle: {
        normal: {
          color: "#6fbae1",
          lineStyle: {
            color: "#6fbae1", // 改变折线颜色
          },
        },
      },
    },
  ],
};

const memoryOptions: {
  tooltip: {
    trigger: string;
  };
  xAxis: {
    type: string;
    boundaryGap: boolean;
    data: number[];
  };
  yAxis: {
    type: string;
    min: number;
    max: number;
    interval: number;
  };
  series: [
    {
      data: number[];
      type: string;
      areaStyle: {
        normal: {
          color: string;
        };
      };
      itemStyle: {
        normal: {
          color: string;
          lineStyle: {
            color: string;
          };
        };
      };
    },
  ];
} = {
  tooltip: {
    trigger: "axis",
  },
  xAxis: {
    type: "category",
    boundaryGap: false,
    data: [],
  },
  yAxis: {
    type: "value",
    min: 0,
    max: 100,
    interval: 20,
  },
  series: [
    {
      data: [],
      type: "line",
      areaStyle: {
        normal: {
          color: "rgb(32, 160, 255)", // 改变区域颜色
        },
      },
      itemStyle: {
        normal: {
          color: "#6fbae1",
          lineStyle: {
            color: "#6fbae1", // 改变折线颜色
          },
        },
      },
    },
  ],
};

/** 设置图表  */
const setCpuChart = (server: ServerVO) => {
  if (!cpuChart.value) {
    return;
  }
  if (cpuOptions.xAxis.data.length >= 8) {
    cpuOptions.xAxis.data.shift();
    cpuOptions.series[0].data.shift();
  }
  cpuOptions.xAxis.data.push(server.time);
  cpuOptions.series[0].data.push(parseFloat(server.cpu.used));
  cpuChart.value.setOption(cpuOptions);
};

const setMemoryChart = (server: ServerVO) => {
  if (!memoryChart.value) {
    return;
  }
  if (memoryOptions.xAxis.data.length >= 8) {
    memoryOptions.xAxis.data.shift();
    memoryOptions.series[0].data.shift();
  }
  memoryOptions.xAxis.data.push(parseFloat(server.cpu.used));
  memoryOptions.series[0].data.push(parseFloat(server.memory.usageRate));
  memoryChart.value.setOption(memoryOptions);
};

const loadData = () => {
  MonitorAPI.getServerInfo().then((data) => {
    sys.value = data.sys;
    cpu.value = data.cpu;
    memory.value = data.memory;
    swap.value = data.swap;
    disk.value = data.disk;
    visible.value = true;
    setCpuChart(data);
    setMemoryChart(data);
  });
};

const handleRefresh = () => {
  visible.value = false;
  loadData();
};

/** 窗口大小变化时，重置图表大小 */
const handleResize = () => {
  setTimeout(() => {
    if (cpuChart.value) {
      cpuChart.value.resize();
    }
    if (memoryChart.value) {
      memoryChart.value.resize();
    }
  }, 100);
};
/** 初始化图表  */
onMounted(() => {
  cpuChart.value = markRaw(
    echarts.init(document.getElementById("cpu_chart") as HTMLDivElement)
  );
  memoryChart.value = markRaw(
    echarts.init(document.getElementById("memory_chart") as HTMLDivElement)
  );

  // 定时获取数据
  intervalId.value = setInterval(() => {
    loadData();
  }, 10000);
  window.addEventListener("resize", handleResize);
});

onBeforeUnmount(() => {
  window.removeEventListener("resize", handleResize);
});

onActivated(() => {
  handleResize();
});

onUnmounted(() => {
  // 清除定时器
  if (intervalId.value) {
    clearInterval(intervalId.value);
  }
});
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .box-card {
  margin-bottom: 5px;
  span {
    margin-right: 28px;
  }
  .el-icon-refresh {
    margin-left: 40px;
    margin-right: 10px;
    float: right;
    cursor: pointer;
  }
}
.cpu,
.memory,
.swap,
.disk {
  width: 20%;
  float: left;
  padding-bottom: 20px;
  margin-right: 5%;
}
.title {
  text-align: center;
  font-size: 15px;
  font-weight: 500;
  color: #999;
  margin-bottom: 16px;
}
.footer {
  text-align: center;
  font-size: 15px;
  font-weight: 500;
  color: #999;
  margin-top: -5px;
  margin-bottom: 10px;
}
.content {
  text-align: center;
  margin-top: 5px;
  margin-bottom: 5px;
}
</style>
